package com.zbkj.service.service.course.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.course.*;
import com.zbkj.common.model.user.User;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.course.CourseUserSearchRequest;
import com.zbkj.common.response.CommonResult;
import com.zbkj.common.response.course.CourseListStudyLogResponse;
import com.zbkj.common.response.course.CourseResponse;
import com.zbkj.common.response.course.CourseUserResponse;
import com.zbkj.service.dao.CourseUserDao;
import com.zbkj.service.service.UserService;
import com.zbkj.service.service.course.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Mr.Zhang
 * @description CourseUserServiceImpl 接口实现
 * @date 2022-07-26
 */
@Service
public class CourseUserServiceImpl extends ServiceImpl<CourseUserDao, CourseUser> implements CourseUserService {

    @Resource
    private CourseUserDao dao;

    @Autowired
    private CourseCodeService courseCodeService;

    @Autowired
    private CourseService courseService;
    @Autowired
    private CourseListService courseListService;
    @Autowired
    private UserService userService;

    @Autowired
    private CourseListStudyLogService courseListStudyLogService;
    @Autowired
    private CourseLabelService courseLabelService;

    /**
     * 列表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<CourseUser>
     * @author Mr.Zhang
     * @since 2022-07-26
     */
    @Override
    public PageInfo<CourseUserResponse> getList(CourseUserSearchRequest request, PageParamRequest pageParamRequest) {

        List<CourseUserResponse> courseUserResponses=new ArrayList<>();


        //带 CourseUser 类的多条件查询
        LambdaQueryWrapper<CourseUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CourseUser::getUid, userService.getUserIdException());
        if (StringUtils.isNotEmpty(request.getName())) {
            lambdaQueryWrapper.like(CourseUser::getName, request.getName());
        }
        Page<CourseUser> page=PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<CourseUser> courseUsers=dao.selectList(lambdaQueryWrapper);
        if(CollectionUtil.isEmpty(courseUsers)){
            return CommonPage.copyPageInfo(page, new ArrayList<>());
        }
        courseUsers.forEach(courseUser -> {
            CourseUserResponse courseUserResponse=new CourseUserResponse();
            BeanUtil.copyProperties(courseUser,courseUserResponse);
            courseUserResponses.add(courseUserResponse);
        });
        if(CollectionUtil.isNotEmpty(courseUserResponses)){
            compareCourseLabels(courseUserResponses);
            compareCourseInfo(courseUserResponses);
        }
        return CommonPage.copyPageInfo(page, courseUserResponses);
    }

    private void compareCourseInfo(List<CourseUserResponse> courseUserResponse){
        List<Integer> courseIds = courseUserResponse.stream().map(CourseUserResponse::getCourseId).collect(Collectors.toList());
        LambdaQueryWrapper<Course> lqw=new LambdaQueryWrapper<>();
        lqw.in(Course::getId,courseIds);
        List<Course> courseList=courseService.list(lqw);
        Map<Integer,Course> courseMap=courseList.stream().collect(Collectors.toMap(Course::getId,t->t));
        courseUserResponse.forEach(courseUserResponse1 -> {
            if(courseMap.containsKey(courseUserResponse1.getCourseId())){
                courseUserResponse1.setPlayCount(courseMap.get(courseUserResponse1.getCourseId()).getPlayCount());
                courseUserResponse1.setListCount(courseMap.get(courseUserResponse1.getCourseId()).getListCount());
            }
        });
    }

    private void compareCourseLabels(List<CourseUserResponse> courseUserResponse) {
        List<Integer> courseIds = courseUserResponse.stream().map(CourseUserResponse::getCourseId).collect(Collectors.toList());
        List<CourseLabel> courseLabels = courseLabelService.getLabelByCourseIds(courseIds);
        if(CollectionUtil.isEmpty(courseLabels))
            return;
        Map<Integer,List<CourseLabel>> labelMap=courseLabels.stream().collect(Collectors.groupingBy(CourseLabel::getCourseId));

        courseUserResponse.forEach(courseUserResponse1 -> {
            if(labelMap.containsKey(courseUserResponse1.getCourseId())){
                courseUserResponse1.setLabels(labelMap.get(courseUserResponse1.getCourseId()));
            }
        });
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> exchangeCourse(String courseCode, Integer courseId) {
        Integer uid=userService.getUserIdException();
        LambdaQueryWrapper<CourseCode> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CourseCode::getCode, courseCode);
        lambdaQueryWrapper.eq(CourseCode::getCourseId, courseId);
        List<CourseCode> courseCodes = courseCodeService.list(lambdaQueryWrapper);
        if (CollectionUtil.isEmpty(courseCodes)) {
            return CommonResult.failed("没有对应的课程码，请联系客服");
        }
        CourseCode code = courseCodes.get(0);
        if (code.getStatus()) {//课程码状态（0：未兑换；1：已兑换；）
//            return CommonResult.failed("该课程码已兑换");
        }
        //增加判断， 判断该用户是否有兑换过该课程
//        lambdaQueryWrapper.clear();
//        lambdaQueryWrapper.eq(CourseCode::getUid,uid);
//        lambdaQueryWrapper.eq(CourseCode::getCourseId,courseId);
//        if(CollectionUtil.isNotEmpty(courseCodeService.list(lambdaQueryWrapper))){
//            return CommonResult.failed("您已兑换过该课程，无需再兑换");
//        }
        if(!checkCourseCode(code,uid)){
            return CommonResult.success("您已兑换过该课程或该验证码兑换次数已用完");
        }
        //更新课程码的兑换数量
        LambdaUpdateWrapper<CourseCode> updateWrapperCode = new LambdaUpdateWrapper<>();
        updateWrapperCode.set(CourseCode::getStatus, true);
        updateWrapperCode.eq(CourseCode::getCode, courseCode);
        updateWrapperCode.eq(CourseCode::getCourseId, courseId);
        updateWrapperCode.setSql(StrUtil.format("exchanged = exchanged + {}",1));
        courseCodeService.update(updateWrapperCode);

        //更新课程兑换数量
        LambdaUpdateWrapper<Course> cuw=new LambdaUpdateWrapper<>();
        cuw.eq(Course::getId,courseId);
        cuw.setSql(StrUtil.format("exchanged = exchanged + {}",1));
        courseService.update(cuw);

        Course course = courseService.getById(courseId);
        CourseUser courseUser = new CourseUser();
        courseUser.setCourseId(courseId);
        courseUser.setCourseCode(courseCode);
        courseUser.setName(course.getName());
        courseUser.setSubName(course.getSubName());
        courseUser.setCateId(course.getCateId());
        courseUser.setUid(userService.getUserIdException());
        courseUser.setImage(course.getImage());
        courseUser.setCreateTime(new Date());
        save(courseUser);

        LambdaQueryWrapper<CourseList> listLambdaQueryWrapper = new LambdaQueryWrapper<>();
        listLambdaQueryWrapper.eq(CourseList::getCourseId, courseId);
        List<CourseList> courseLists = courseListService.list(listLambdaQueryWrapper);
        if (CollectionUtil.isEmpty(courseLists)) {
            return CommonResult.success();
        }

        List<CourseListStudyLog> listStudyLogs = new ArrayList<>();
        courseLists.forEach(courseList -> {
            CourseListStudyLog studyLog = new CourseListStudyLog();
            BeanUtil.copyProperties(courseList, studyLog);
            studyLog.setUid(userService.getUserIdException());
            studyLog.setId(null);
            studyLog.setCourseListId(courseList.getId());
            studyLog.setStatus(0);//订单状态（0：未学习；1：学习中；2：已完成）
            studyLog.setCreateTime(new Date());
            studyLog.setUpdateTime(null);
            listStudyLogs.add(studyLog);
        });
        if (CollectionUtil.isNotEmpty(listStudyLogs)) {
            courseListStudyLogService.saveBatch(listStudyLogs);
        }
        return CommonResult.success();
    }


    private boolean checkCourseCode(CourseCode courseCode,Integer uid){
        LambdaQueryWrapper<CourseUser> lqw=new LambdaQueryWrapper<>();
        lqw.eq(CourseUser::getCourseCode,courseCode.getCode());
        int courseUserCount=this.count(lqw);
        if(courseUserCount>=courseCode.getExchangeCount()){
            return false;
        }
        lqw.eq(CourseUser::getUid,uid);
        courseUserCount=this.count(lqw);
        if(courseUserCount>0){
            return false;
        }
        return true;
    }

    @Override
    public CourseResponse detailFront(Integer id) {
        Course course = courseService.getById(id);
        //获取课程目录
        LambdaQueryWrapper<CourseList> courseListLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseListLambdaQueryWrapper.eq(CourseList::getCourseId, id);
        List<CourseList> courseLists = courseListService.list(courseListLambdaQueryWrapper);
        CourseResponse courseResponse = new CourseResponse();
        BeanUtil.copyProperties(course, courseResponse);
//        courseResponse.setCourseLists(courseLists);
        //todo
        LambdaQueryWrapper<CourseListStudyLog> logLambdaQueryWrapper = new LambdaQueryWrapper<>();
        logLambdaQueryWrapper.eq(CourseListStudyLog::getCourseId, id);
        logLambdaQueryWrapper.eq(CourseListStudyLog::getUid, userService.getUserIdException());
        List<CourseListStudyLog> courseListStudyLogs = courseListStudyLogService.list(logLambdaQueryWrapper);
        Map<Integer, CourseListStudyLog> courseListStudyLogMap = new HashMap<>();
        List<CourseListStudyLog> addLogs = new ArrayList<>();//如果课程新增了章节，则要添加学习的课程目录的记录
        if (CollectionUtil.isNotEmpty(courseListStudyLogs)) {
            courseListStudyLogMap = courseListStudyLogs.stream().collect(Collectors.toMap(CourseListStudyLog::getCourseListId, t -> t));
            for(CourseList courseList:courseLists){
                if(!courseListStudyLogMap.containsKey(courseList.getId())){
                    CourseListStudyLog studyLog = new CourseListStudyLog();
                    BeanUtil.copyProperties(courseList, studyLog);
                    studyLog.setUid(userService.getUserIdException());
                    studyLog.setId(null);
                    studyLog.setStatus(0);//订单状态（0：未学习；1：学习中；2：已完成）
                    studyLog.setCreateTime(new Date());
                    studyLog.setUpdateTime(null);
                    addLogs.add(studyLog);
                }
            }
        } else {
            //
            courseLists.forEach(courseList -> {
                CourseListStudyLog studyLog = new CourseListStudyLog();
                BeanUtil.copyProperties(courseList, studyLog);
                studyLog.setUid(userService.getUserIdException());
                studyLog.setId(null);
                studyLog.setStatus(0);//订单状态（0：未学习；1：学习中；2：已完成）
                studyLog.setCreateTime(new Date());
                studyLog.setUpdateTime(null);
                addLogs.add(studyLog);
            });
        }
        courseListStudyLogService.saveBatch(addLogs);
        courseListStudyLogs = courseListStudyLogService.list(logLambdaQueryWrapper);

        Map<Integer,CourseList> courseListMap=courseLists.stream().collect(Collectors.toMap(CourseList::getId,t->t));
        List<CourseListStudyLogResponse> courseListStudyLogResponses=new ArrayList<>();
        courseListStudyLogs.forEach(courseListStudyLog -> {
            CourseListStudyLogResponse courseListStudyLogResponse=new CourseListStudyLogResponse();
            BeanUtil.copyProperties(courseListStudyLog,courseListStudyLogResponse);
            CourseList courseList=courseListMap.get(courseListStudyLog.getCourseListId());
            courseListStudyLogResponse.setPlayCount(courseList.getPlayCount());
            courseListStudyLogResponses.add(courseListStudyLogResponse);
        });

        courseResponse.setCourseListStudyLogs(courseListStudyLogResponses);
        courseResponse.setLabels(courseLabelService.getLabelByCourseId(id));
        return courseResponse;
    }
}

